// Author: Domien Nowicki

#include <fstream>
#include <iostream>
#include <sstream>

#include "Player.h"
#include "MapBacktrack.h"
#include "Game.h"

using namespace std;

Player::Player(Game *newGame, Map* newMap, const Properties& newProperties): map(newMap), game(newGame), steps(0), properties(newProperties), mapSolver(0), human(false)
{
}

Player::Player(const Player& rhs) 
{
	
}

Player::~Player()
{
	// Clear map solver if allocated
	if (mapSolver)
	{
		delete mapSolver;
		mapSolver = 0;
	}
}


// Set if this is a human player
void Player::SetHuman(bool state)
{
	human = true;
}

bool Player::IsHuman() const
{
	return human;
}

// Get the map assigned to this player
Map* Player::GetMap() const
{
	return map;
}

// Set default color
void Player::SetColor(Color newColor)
{
	color = newColor;
}

// Restrict the map solver to a particular color amount
void Player::RestrictMapSolver(int colorCount)
{
	properties.SetColorCount(colorCount);
}

// Get a hint
void Player::GetHintMove(Move *move)
{
	// Make a temporary map solver
	MapSolver *tmpMapSolver = new MapBacktrack(*map, properties);

	// Get hint
	*move = tmpMapSolver->HintMove();

	// Change the map pointer to the assigned player's map instead of the temporary copied one
	move->SetMap(this->map);

	// And destroy the map solver
	delete tmpMapSolver;
}


bool Player::GetMove(Move *move)
{
	// if this is the first time get move is called
	if (0 == mapSolver)
	{
		// Create a new map solver
		mapSolver = new MapBacktrack(*map, properties);

		// And initialize it
		mapSolver->Initialize();
	}

	// Get the next move
	*move = mapSolver->NextMove();

	// Change the map pointer to the assigned player's map instead of the temporary copied one
	move->SetMap(this->map);

	return true;
}

void Player::StepIncrease()
{
	// Increase the steps count
	steps++;
}


void Player::DoMove(const Move& move)
{
	// Do a move to the game assigned to this player
	game->DoMove(this, move);
	
}

int Player::GetStepCount() const
{
	return steps;
}
